using System.ComponentModel;
using System.Runtime.Serialization;

using SharpGL.Media3D;
using SharpGL.SceneGraph.Helpers;

namespace SharpGL.SceneGraph.Quadrics
{
    /// <summary>
    /// The Disk class wraps both the disk and partial disk quadrics.
    /// </summary>
    [DataContract(IsReference = true)]
    public class Disk : Quadric
    {
        #region Private Fields

        //	Disk data.
        [DataMember]
        private double innerRadius = 0.0;
        [DataMember]
        private double outerRadius = 1.0;
        [DataMember]
        private double startAngle = 0.0;
        [DataMember]
        private double sweepAngle = 360.0;
        [DataMember]
        private int slices = 3;
        [DataMember]
        private int loops = 3;

        /// <summary>
        /// The bounding volume helper, used to aid implementation of IVolumeBound.
        /// </summary>
        private BoundingVolumeHelper boundingVolumeHelper = new BoundingVolumeHelper();

        #endregion Private Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Disk"/> class.
        /// </summary>
        public Disk() 
        {
            //  Set the name.
            Name = "Disk";

            //  Set the bounding volume.
            boundingVolumeHelper.BoundingVolume.FromCylindricalVolume(new Point3D(0.0f, 0.0f, 0.0f), 0.0f, (float)outerRadius, (float)outerRadius);
        }

        #endregion Constructors

        #region Public Methods

        /// <summary>
        /// Render to the provided instance of OpenGL.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        /// <param name="renderMode">The render mode.</param>
        public override void Render(OpenGL gl, RenderMode renderMode)
        {
            //  Call the base.
            base.Render(gl, renderMode);
            
            //	Draw a quadric with the current settings.
            gl.PartialDisk(glQuadric, innerRadius, outerRadius,
                            slices, loops, startAngle, sweepAngle);
        }

        #endregion Public Methods

        #region Public Properties

        /// <summary>
        /// Gets or sets the inner radius.
        /// </summary>
        /// <value>
        /// The inner radius.
        /// </value>
        [Description("Radius of the hole on the inside of the disk."), Category("Quadric")]
        public double InnerRadius
        {
            get { return innerRadius; }
            set { innerRadius = value; }
        }

        /// <summary>
        /// Gets or sets the outer radius.
        /// </summary>
        /// <value>
        /// The outer radius.
        /// </value>
        [Description("Radius of the disk."), Category("Quadric")]
        public double OuterRadius
        {
            get { return outerRadius; }
            set
            {
                outerRadius = value;

                //  Update the bounding volume.
                BoundingVolume.FromCylindricalVolume(new Point3D(0.0f, 0.0f, 0.0f), 0.0f, (float)outerRadius, (float)outerRadius);
            }
        }

        /// <summary>
        /// Gets or sets the start angle.
        /// </summary>
        /// <value>
        /// The start angle.
        /// </value>
        [Description("Start angle of the partial disk."), Category("Quadric")]
        public double StartAngle
        {
            get { return startAngle; }
            set { startAngle = value; }
        }

        /// <summary>
        /// Gets or sets the sweep angle.
        /// </summary>
        /// <value>
        /// The sweep angle.
        /// </value>
        [Description("Size of the partial disk."), Category("Quadric")]
        public double SweepAngle
        {
            get { return sweepAngle; }
            set { sweepAngle = value; }
        }

        /// <summary>
        /// Gets or sets the slices.
        /// </summary>
        /// <value>
        /// The slices.
        /// </value>
        [Description("Number of slices."), Category("Quadric")]
        public int Slices
        {
            get { return slices; }
            set { slices = value; }
        }

        /// <summary>
        /// Gets or sets the loops.
        /// </summary>
        /// <value>
        /// The loops.
        /// </value>
        [Description("Number of loops."), Category("Quadric")]
        public int Loops
        {
            get { return loops; }
            set { loops = value; }
        }

        /// <summary>
        /// Gets the bounding volume.
        /// </summary>
        [Browsable(false)]
        public BoundingVolume BoundingVolume
        {
            get { return boundingVolumeHelper.BoundingVolume; }
        }

        #endregion Public Properties
    }
}